Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AttitudeController interface #2881

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from

Conversation

thexa4
Copy link
Contributor

@thexa4 thexa4 commented Feb 21, 2021

Adds a generalized interface that allows querying information about Attitude Controllers like control surfaces, reaction wheels, rotors, drain valves and engines: ship:attitudecontroller

Currently works great for reaction wheels but for the rest it has to make a lot of assumptions.

Also adds moment of inertia property to ship: ship:momentOfInertia

TODO:

  • Add missing AttitudeCorrectionResult struct doc page
  • Expose and document the authority limiter attributes

@thexa4 thexa4 marked this pull request as ready for review March 20, 2021 22:52
@thexa4
Copy link
Contributor Author

thexa4 commented Mar 20, 2021

The feature is fully implemented but as of yet very lightly tested. If there's anyone that would like to help test this out feel free to send me a message.

@nuggreat
Copy link

Mostly just skimming the documentation at this point bit I have some things I feel should be raised.

Why have you separated out the limiters for rotation and translation the in game GUIs do not. I assume that its is because there is a difference in the API. But in that case we try to follow the conventions of the GUI so there should be one limiter that sets both elements.

Translation should not be described as v(x, y, z) as there is enough confusion with people assuming that the raw x/y/z values you get from all vectors align to there craft in all cases. Also for some one new to vector space arbitrary x/y/z means nothing to them thus it is better to describe things as star/top/fore. This also needs to be done this way as to match the other translation documentation within kOS. And what ever order they need to be in that multiplying the generated vector by SHIP:FACING will convert from the ship axis aligned frame to something in the frame that positions and velocity vectors exist in. This ability to just multiply by a rotation to change frames should also function for the computed torque vector in the AttitudeCorrectionResult structure.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 20, 2021

Thanks for the review.

Why have you separated out the limiters for rotation and translation the in game GUIs do not.

This is because for engines you need to be able to set both independently. There is no sensible mapping that exists between the thrust limiter and the gimbal limiter.

Translation should not be described as v(x, y, z)

I agree, will change the documentation

This ability to just multiply by a rotation to change frames should also function for the computed torque vector in the AttitudeCorrectionResult structure.

What would a rotated torque vector mean? I can understand that you want to be able to rotate the translation ones, which should certainly be the case for them to be consistent.

@nuggreat
Copy link

This is because for engines you need to be able to set both independently. There is no sensible mapping that exists between the thrust limiter and the gimbal limiter.

Then split things between along the lines of thrust limiter and authority/gimbal limiter.

What would a rotated torque vector mean

The whole point of being able to rotate would be that you could keep more of the control math and logic in the vector space where any given computation does 3x the work that you would get if you where in working in scalars for all axies. As it stands in kOS if you compute a translation error vector in the SHIP-RAW frame and then rotate it by SHIP:FACING:INVERSE you can basically plug that strait into SHIP:CONTROLS:TRANSLATION with out needing to break things out into there individual axis. Thus it would be nice if that also existed for the rotation axis. As the farther you can get before you need to do the better, and if the need to use several dotproducts to manually do the rotation can be avoided it would be nice.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 21, 2021

Then split things between along the lines of thrust limiter and authority/gimbal limiter.

I think I might be confused, isn't that how it's split it so far?

Thus it would be nice if that also existed for the rotation axis

I agree that that would be nice, but as far as I know you can't do that with Euler rotations. Interpreting a <yaw, pitch, roll> tuple as a vector and rotating that will not result in anything usable.
We could return a quaternion (kOS DIRECTION structure) to make them not be Euler based. Unfortunately that would also be confusing because you can't use torque as an actual rotation.

@nuggreat
Copy link

nuggreat commented Mar 21, 2021

I think I might be confused, isn't that how it's split it so far?

The documentation uses "ROTATIONAUTHRORITYLIMITER" and "TRANSLATIONAUTHRORITYLIMITER" which instantly made me think that for RCS blocks you had some how split the single limiter into two different limiters one that applied only to roll/pitch/yaw inputs and the other to star/top/for inputs.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 21, 2021

Ah, ok. I'll try to make the documentation clearer. They are not necessarily independent. RCS does not support having a different limiter for translation and rotation. Setting one will set the other in this case.

@nuggreat
Copy link

As for the torque thing because you are also adding a MOI vector as well I was mostly hoping that combining torque and the MOI as vectors using the standard physics equations would result in an angular acceleration vector which when multiplied by time naturally results in an angular velocity vector which could then be compared directly against SHIP:ANGULARVEL. And all of that with out needing to do axis swapping simply applying the SHIP:FACINGorSHIP:FACING:INVERSE` as needed to change frames was more what I was after with those thoughts. I do apologize for my lack of clarity there.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 21, 2021

Right. The part about combining it with the MOI should work and will give you an acceleration. The problem is that an angular acceleration cannot be integrated over time using simple multiplication.

An example would be a spacecraft that rolls and pitches at the same acceleration; doing that will keep your ship orientation locked in a small circle. When you multiply by time you would get a path that keeps pitching and independently rolls which is not the case.

Figuring out what the optimal path is through pitch, yaw, roll to achieve a desired endstate is unfortunately not trivial. (not even with manual axis swapping)

@nuggreat
Copy link

nuggreat commented Mar 21, 2021

Good point forgot about that but still the linear approximation should be usable more or less out of the box. I was mostly just trying to make a note that it would need to be tested if it wasn't directly usable altered so that things line up.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 30, 2021

Related to #521, #351 and #690

@Dunbaratu
Copy link
Member

I've finally gotten around to looking at this line by line in detail.

It seems there's a bit of duplication from how calculating available torque for an attitude controller looks very similar to code in SteeringManager.CorrectedGetPotentialTorque(). I think it would be better if a way could be found to share the same code path for both purposes so bug fixes affect both of them.

Here's an Example - The RCS blocks have alternate variants with the nozzles pointing slightly different directions, instead of just returning the 4 transforms that actually exist, it returns like 12 of them for all possible alternate nozzle positions. If you don't cull out the extras by ignoring ones where rcsTransform.gameObject.activeInHierarchy is false, the RCS torque calculation is 2 to 3 times too large. This bug fix is in SteeringManager but missing from AttitudeControllerRCS because they don't share the same code path for the shared purpose of walking the RCS transforms.

That's just one example, but I'm nervous about the duplication between the two for all the torque providers for things like that.

@Dunbaratu
Copy link
Member

Okay, I missed it before, but it does look like it's calling SteeringManager.CorrectedGetPotentialTorque() after all. That's a good thing. So far other than the typo in the suffix name ('Authrority'), so far things look like they're working.

  1 - Elsewhere in kOS, the project uses the standard that
  Properties are capitalized just like Methods are.  (Only
  local vars and fields that are passive (no getter/setter) are
  lowercased.)

  2 - I renamed ``vesselTransform`` and ``vesselRotation`` inside
  SteeringManger.FindMOI() to ``vesTransform`` and ``vesRotation``.
  This is just a matter of preference that I'd like to make the names
  explicitly tell the reader these differ from the instance members of
  the same name.  (i.e. not having to depend on noticing the method is
  static to realize what's going on.)

I also started to write up more explicit documentation, where I would
test each suffix and then write a more detailed description of what it
does, but I didn't get past the first paragraph.  I stopped when I
started noticing how many of these suffixes are just hardcoded stubs
for now that aren't actually implemented.  I didn't realize most of
the suffixes are just placeholders until I started trying to document
them.

(AllowPitch, AllowRoll,
AllowYaw, AllowX, AllowY, AllowZ, RotationAuthorityLimiter,
TranslationAuthorityLimiter, HasCustomThrottle, CustomThrottle,
ControllerType, Status, ResponseTime.)
@Dunbaratu
Copy link
Member

Dunbaratu commented Jul 12, 2021

@thexa4 I don't know if you're still reading this, but if you are let me know if you wanted to work on it more or not. I was trying to document it a bit more when I noticed a lot of the suffixes I was going to describe are just temporary stubs that don't do anything yet. The ones that are implemented look like they work great. I can take what you gave me and finish it. If I do that I may cut out some of the un-implemented stubs rather than finish them. They may be hard to implement in a universal way for all AttitudeControllers (i.e. not every controller has a toggle for not responding to pitch/yaw/roll for example) and it might be better just to not have those suffixes instead of having them but having them hard to implement right.

I submitted a PR to your PR (thexa4#3). If you want to see what I did so far in my attempt to merge this before I stopped, look there. (My PR to your PR looks like a LOT of diffs but that's only because I updated to the latest Develop first. If you update your PR to the latest develop most of those diffs should go away and all that's left is a few variable renamings.)

@thexa4
Copy link
Contributor Author

thexa4 commented Jul 20, 2021

Thanks for the changes, I merged them in. I wasn't able to find any stubs that were accidentally unimplemented. A lot of the setters are not implemented because the underlying part does not support them.
I've added a warning about checking whether setting it works to the documentation. I believe that supporting the toggles in the controller interface where possible provides a lot of value; Would adding the documentation change address the concern about them not behaving the same everywhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants